﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL;

namespace bitzhuwei.SharpGLController
{
    /// <summary>
    /// A visual way to control your view.
    /// </summary>
    public partial class SharpGLPanel : UserControl
    {
        private OpenGL gl;
        private string aspect;
        private string zNear;

        public SharpGLPanel()
        {
            InitializeComponent();
            UpdateTextBoxValue();
        }

        public SharpGLPanel(OpenGL gl)
        {
            InitializeComponent();

            UpdateTextBoxValue();
            this.gl = gl;
        }

        public void SetOpenGL(OpenGL gl)
        {
            this.gl = gl;
        }

        private void View_ValueChanged(object sender, EventArgs e)
        {
            if (gl == null) return;
            decimal aspect = 0.0m;
            if (decimal.TryParse(txtPerspectiveAspect.Text, out aspect))
            {
                decimal zNear = 0.0m;
                if (decimal.TryParse(txtPerspectiveZNear.Text, out zNear))
                {
                    var perspectiveParam = new PerspectiveParam(numPerspectiveFovy.Value, aspect,
                        zNear, numPerspectiveZFar.Value);
                    var lookAtParam = new LookAtParam(numLookAtEyeX.Value, numLookAtEyeY.Value, numLookAtEyeZ.Value,
                        numLookAtCenterX.Value, numLookAtCenterY.Value, numLookAtCenterZ.Value,
                        numLookAtUpX.Value, numLookAtUpY.Value, numLookAtUpZ.Value);

                    //  Set the projection matrix.
                    gl.MatrixMode(OpenGL.GL_PROJECTION);

                    //  Load the identity.
                    gl.LoadIdentity();

                    //  Create a perspective transformation.
                    gl.Perspective(perspectiveParam.fovy, perspectiveParam.aspect, perspectiveParam.zNear, perspectiveParam.zFar);
                   
                    //  Use the 'look at' helper function to position and aim the camera.
                    gl.LookAt(lookAtParam.eye.X, lookAtParam.eye.Y, lookAtParam.eye.Z,
                        lookAtParam.center.X, lookAtParam.center.Y, lookAtParam.center.Z,
                        lookAtParam.up.X, lookAtParam.up.Y, lookAtParam.up.Z);

                    //  Set the modelview matrix.
                    gl.MatrixMode(OpenGL.GL_MODELVIEW);
                    UpdateTextBoxValue();
                }
                else
                {
                    txtPerspectiveZNear.Text = this.zNear;
                }
            }
            else
            {
                txtPerspectiveAspect.Text = this.aspect;
            }
        }

        private void UpdateTextBoxValue()
        {
            this.aspect = txtPerspectiveAspect.Text;
            this.zNear = txtPerspectiveZNear.Text;
        }
    }
}
